/*
 * @(#)RegisterAlclbListener.java   1.0  2021年9月10日
 * 
 * Copyright (c)	2014-2020. All Rights Reserved.	GuangZhou hhmk Technology Company LTD.
 */
package com.swift.register.alclb;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.aliyun.slb20140515.models.DescribeVServerGroupAttributeResponseBody.DescribeVServerGroupAttributeResponseBodyBackendServersBackendServer;
import com.aliyuncs.ecs.model.v20140526.DescribeInstancesResponse.Instance;
import com.swift.core.env.Env;
import com.swift.core.env.EnvLoader;
import com.swift.core.server.LifeCycle;
import com.swift.core.server.ServerStartedListener;
import com.swift.register.alclb.api.ClbApi;
import com.swift.register.alclb.api.EcsApi;
import com.swift.register.alclb.model.BackendServer;
import com.swift.register.alclb.model.ClbRule;
import com.swift.util.type.IpUtil;
import com.swift.util.type.TypeUtil;


/**
 * 添加说明 
 * @author zhengjiajin
 * @version 1.0 2021年9月10日
 */
@Component
public class RegisterAlclbListener implements ServerStartedListener {

    private static Logger log = LoggerFactory.getLogger(RegisterAlclbListener.class);
    @Autowired
    private EcsApi ecsApi;
    
    @Autowired
    private ClbApi clbApi;
    
    @Value("${sysId:}")
    private String sysId;
    
    @Value("${domain:}")
    private String domain;
    
    @Value("${aliyun.register.clb:}")
    private String clbid;
    /** 
     * @see com.swift.core.server.ServerStartedListener#listener(com.swift.core.server.LifeCycle)
     */
    @Override
    public void listener(LifeCycle lifeCycle) {
        if(!lifeCycle.protocol().equals("http")) return;
        if(TypeUtil.isNull(sysId)) return;
        if(TypeUtil.isNull(domain)) return;
        if(TypeUtil.isNull(clbid)) return;
        //开发环境不注册
        if(EnvLoader.getEnv().equals(Env.DEV)) return;
        //得到服务器ID
        Instance instance = ecsApi.getEcsInstanceId(IpUtil.getHostAddress());
        log.info("服务器ID:"+instance);
        if(TypeUtil.isNull(instance)) return;
        //自己检测创建虚拟服务器组
        String vServerGroupId = clbApi.autoVServerGroup(sysId);
        log.info("虚拟服务器组ID:"+vServerGroupId);
        if(TypeUtil.isNull(vServerGroupId)) return;
        //找到虚拟服务器组内现有服务器
        List<DescribeVServerGroupAttributeResponseBodyBackendServersBackendServer> list = clbApi.getDescribeVServerGroupAttribute(vServerGroupId);
        //删除没启动的虚拟服务器组
        removeVServerGroupBackendServers(vServerGroupId,list);
        //把自身添加进虚拟服务器组内
        if(!checkVServerGroupBackendServers(instance, lifeCycle, list)) {
            addVServerGroupBackendServers(vServerGroupId,instance, lifeCycle, list);
        }
        //检测CLB监听端口是否开启
        ClbRule clbRule = new ClbRule();
        clbRule.setDomain(sysId+"."+domain);
        clbRule.setRuleName(sysId);
        //clbRule.setUrl(url);
        clbRule.setVServerGroupId(vServerGroupId);
        clbApi.autoRules(80, clbRule);
        clbApi.autoRules(443, clbRule);
    }
    /**
     * 检测自身是否已经存在
     * @param lifeCycle
     * @param list
     * @return
     */
    private boolean checkVServerGroupBackendServers(Instance instance ,LifeCycle lifeCycle,List<DescribeVServerGroupAttributeResponseBodyBackendServersBackendServer> list) {
        if(TypeUtil.isNull(list)) return false;
        for(DescribeVServerGroupAttributeResponseBodyBackendServersBackendServer server:list) {
            if(server.getServerId().equals(instance.getInstanceId()) && server.getPort().intValue()==lifeCycle.getPort()) {
                return true;
            }
        }
        return false;
    }
    
    private void addVServerGroupBackendServers(String vServerGroupId,Instance instance ,LifeCycle lifeCycle,List<DescribeVServerGroupAttributeResponseBodyBackendServersBackendServer> list) {
        BackendServer backendServer = new BackendServer();
        backendServer.setDescription(sysId);
        backendServer.setPort(TypeUtil.toString(lifeCycle.getPort()));
        backendServer.setServerId(instance.getInstanceId());
        backendServer.setServerIp(IpUtil.getHostAddress());
        backendServer.setType("ecs");//固定,不支持弹性网卡
        backendServer.setWeight("100");
        clbApi.addVServerGroupBackendServers(vServerGroupId, backendServer);
    }
    
    private void removeVServerGroupBackendServers(String vServerGroupId,List<DescribeVServerGroupAttributeResponseBodyBackendServersBackendServer> list) {
        if(TypeUtil.isNull(list)) return;
        for(DescribeVServerGroupAttributeResponseBodyBackendServersBackendServer server:list) {
            String ip = ecsApi.getIp(ecsApi.getInfo(server.getServerId()));
            if(!IpUtil.checkRemovePort(ip, server.getPort())) {
                BackendServer backendServer = new BackendServer();
                backendServer.setServerId(server.getServerId());
                backendServer.setDescription(server.getDescription());
                backendServer.setPort(TypeUtil.toString(server.getPort()));
                backendServer.setServerIp(ip);
                backendServer.setType(server.getType());
                backendServer.setWeight(TypeUtil.toString(server.getWeight()));
                clbApi.removeVServerGroupBackendServers(vServerGroupId, backendServer);
            }
        }
    }
    
}
